package com.desaysv.mvp;

import android.util.Log;

import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;

/**
 * p层基类
 *
 * @param <T> view层
 * @param <E> model层
 * @author uidq5208
 * @version 1.0
 * @since 2022-12-26
 */
public class BasePresenter<T extends IView, E extends IModel> {
    /**
     * 日志标识
     */
    private static final String TAG = "[BasePresenter]";
    /**
     * view层
     */
    private WeakReference<IView> mView = null;
    /**
     * model层
     */
    private E mModel = null;

    /**
     * 绑定view层
     *
     * @param view view层视图
     */
    protected void attach(IView view) {
        Log.i(TAG, "attach: bindIView");
        this.mView = new WeakReference<>(view);
        initModel();
    }

    /**
     * 获取view层对象
     *
     * @return view层实例
     */
    protected T getView() {
        return (T) mView.get();
    }

    /**
     * 获取model层对象
     *
     * @return model层实例
     */
    protected E getModel() {
        return mModel;
    }

    /**
     * 解除view/model层绑定
     */
    protected void onDestory() {
        this.mView = null;
        this.mModel = null;
    }


    /******读取配置的model层，并进行初始化*******/
    private void initModel() {
        if (mModel != null) {
            return;
        }
        //识别泛型类
        Type[] tc = ((ParameterizedType) Objects.requireNonNull(this.getClass().getGenericSuperclass())).getActualTypeArguments();

        Class<E> modelClass = null;
        parent:
        for (Type type : tc) {
            //识别泛型类父级接口
            Class[] clas = ((Class) type).getInterfaces();
            node2:
            for (Class cla : clas) {
                if (cla.equals(IModel.class)) {
                    modelClass = (Class<E>) type;
                    break node2;
                }
                //识别当前类父级接口
                Class[] clasParent = cla.getInterfaces();
                node3:
                for (Class aClass : clasParent) {
                    if (aClass.equals(IModel.class)) {
                        modelClass = (Class<E>) type;
                        break node2;
                    }
                }
            }
            if (modelClass != null) {
                break parent;
            }
        }
        mModel = getPublic(modelClass);
        if (mModel == null) {
            mModel = getPrivate(modelClass);
        }
    }

    /**********初始化Model层的工具方法 start***********/
    private E getPublic(Class<E> t) {
        E temp = null;
        try {
            IModel iproxy = (IModel) t.newInstance();
            temp = (E) iproxy;
        } catch (Exception e) {
            Log.e(TAG, "public init fail!!!");
        }
        return temp;
    }

    private E getPrivate(Class<E> t) {
        E temp = null;
        try {
            Constructor<?>[] conns = t.getDeclaredConstructors();
            IModel iproxy = null;
            for (Constructor<?> conn : conns) {
                try {
                    conn.setAccessible(true);
                    iproxy = (IModel) conn.newInstance();
                    break;
                } catch (Exception e) {
                    Log.e(TAG, "private method init fail!!!");
                }
            }
            temp = (E) iproxy;
        } catch (Exception e) {
            Log.e(TAG, "private init fail!!!");
        }
        return temp;
    }
    /**********初始化Model层的工具方法 end***********/
}
